
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>rom Package &#8212; rom 1.0.4 documentation</title>
    <link rel="stylesheet" href="_static/classic.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    
    <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/underscore.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    
    <link rel="index" title="Index" href="genindex.html" />
    <link rel="search" title="Search" href="search.html" />
    <link rel="next" title="columns Module" href="columns.html" />
    <link rel="prev" title="Welcome to the documentation for the Redis object Mapper" href="index.html" /> 
  </head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="columns.html" title="columns Module"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="index.html" title="Welcome to the documentation for the Redis object Mapper"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">rom 1.0.4 documentation</a> &#187;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="rom-package">
<h1>rom Package<a class="headerlink" href="#rom-package" title="Permalink to this headline">¶</a></h1>
<a class="reference external image-reference" href="https://travis-ci.org/josiahcarlson/rom"><img alt="https://travis-ci.org/josiahcarlson/rom.svg?branch=master" src="https://travis-ci.org/josiahcarlson/rom.svg?branch=master" /></a>
<p>Rom - the Redis object mapper for Python</p>
<p>Copyright 2013-2021 Josiah Carlson</p>
<p>Released under the LGPL license version 2.1 and version 3 (you can choose
which you’d like to be bound under).</p>
<div class="section" id="sponsorships-available">
<h2>Sponsorships Available<a class="headerlink" href="#sponsorships-available" title="Permalink to this headline">¶</a></h2>
<p>Don’t like LGPL? Sponsor the project and get almost any license you want.</p>
<p>This project has been partly sponsored by structd.com . Historically,
rom has been used to help support the delivery of millions of food orders for
chownow.com, and has been used as the primary backend and prototype for several
startups that have made it all the way to series A.</p>
<p>Thank you to our sponsors and those who have consumed our services.</p>
<p>You are welcome for the good service.</p>
<p>Your company link here.</p>
</div>
<div class="section" id="documentation">
<h2>Documentation<a class="headerlink" href="#documentation" title="Permalink to this headline">¶</a></h2>
<p>Updated documentation can be found: <a class="reference external" href="https://josiahcarlson.github.io/rom/">https://josiahcarlson.github.io/rom/</a></p>
</div>
<div class="section" id="what">
<h2>What<a class="headerlink" href="#what" title="Permalink to this headline">¶</a></h2>
<p>Rom is a package whose purpose is to offer active-record style data modeling
within Redis from Python, similar to the semantics of Django ORM, SQLAlchemy,
Google’s Appengine datastore, and others.</p>
</div>
<div class="section" id="why">
<h2>Why<a class="headerlink" href="#why" title="Permalink to this headline">¶</a></h2>
<p>I was building a personal project, wanted to use Redis to store some of my
data, but didn’t want to hack it poorly. I looked at the existing Redis object
mappers available in Python, but didn’t like the features and functionality
offered.</p>
</div>
<div class="section" id="what-is-available">
<h2>What is available<a class="headerlink" href="#what-is-available" title="Permalink to this headline">¶</a></h2>
<p>Data types:</p>
<ul class="simple">
<li>Strings (2.x: str/unicode, 3.3+: str), ints, floats, decimals, booleans</li>
<li>datetime.datetime, datetime.date, datetime.time</li>
<li>Json columns (for nested structures)</li>
<li>OneToMany and ManyToOne columns (for model references)</li>
<li>Non-rom ForeignModel reference support</li>
</ul>
<p>Indexes:</p>
<ul class="simple">
<li>Numeric range fetches, searches, and ordering</li>
<li>Full-word text search (find me entries with col X having words A and B)</li>
<li>Prefix matching (can be used for prefix-based autocomplete)</li>
<li>Suffix matching (can be used for suffix-based autocomplete)</li>
<li>Pattern matching on string-based columns</li>
<li>All indexing except Geo indexing is available when using Redis 2.6.0 and
later</li>
<li>Geo indexing available with Redis 3.2.0 and later</li>
</ul>
<p>Other features:</p>
<ul class="simple">
<li>Per-thread entity cache (to minimize round-trips, easy saving of all
entities)</li>
<li>The ability to cache query results and get the key for any other use (see:
<code class="docutils literal notranslate"><span class="pre">Query.cached_result()</span></code>)</li>
</ul>
</div>
<div class="section" id="getting-started">
<h2>Getting started<a class="headerlink" href="#getting-started" title="Permalink to this headline">¶</a></h2>
<ol class="arabic">
<li><p class="first">Make sure you have Python 2.6, 2.7, or 3.3+ installed</p>
</li>
<li><p class="first">Make sure that you have Andy McCurdy’s Redis client library installed:
<a class="reference external" href="https://github.com/andymccurdy/redis-py/">https://github.com/andymccurdy/redis-py/</a> or
<a class="reference external" href="https://pypi.python.org/pypi/redis">https://pypi.python.org/pypi/redis</a></p>
</li>
<li><p class="first">Make sure that you have the Python 2 and 3 compatibility library, ‘six’
installed: <a class="reference external" href="https://pypi.python.org/pypi/six">https://pypi.python.org/pypi/six</a></p>
</li>
<li><p class="first">(optional) Make sure that you have the hiredis library installed for Python</p>
</li>
<li><p class="first">Make sure that you have a Redis server installed and available remotely</p>
</li>
<li><p class="first">Update the Redis connection settings for <code class="docutils literal notranslate"><span class="pre">rom</span></code> via
<code class="docutils literal notranslate"><span class="pre">rom.util.set_connection_settings()</span></code> (other connection update options,
including per-model connections, can be read about in the <code class="docutils literal notranslate"><span class="pre">rom.util</span></code>
documentation):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">redis</span>
<span class="kn">from</span> <span class="nn">rom</span> <span class="k">import</span> <span class="n">util</span>

<span class="n">util</span><span class="o">.</span><span class="n">set_connection_settings</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="s1">&#39;myhost&#39;</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="mi">7</span><span class="p">)</span>
</pre></div>
</div>
</li>
</ol>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">If you forget to update the connection function, rom will attempt
to connect to localhost:6379 .</p>
</div>
<ol class="arabic" start="7">
<li><p class="first">Create a model:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">rom</span>

<span class="c1"># All models to be handled by rom must derived from rom.Model</span>
<span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="n">rom</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">email</span> <span class="o">=</span> <span class="n">rom</span><span class="o">.</span><span class="n">String</span><span class="p">(</span><span class="n">required</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">unique</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">suffix</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
    <span class="n">salt</span> <span class="o">=</span> <span class="n">rom</span><span class="o">.</span><span class="n">String</span><span class="p">()</span>
    <span class="nb">hash</span> <span class="o">=</span> <span class="n">rom</span><span class="o">.</span><span class="n">String</span><span class="p">()</span>
    <span class="n">created_at</span> <span class="o">=</span> <span class="n">rom</span><span class="o">.</span><span class="n">Float</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">)</span>
</pre></div>
</div>
</li>
<li><p class="first">Create an instance of the model and save it:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">PASSES</span> <span class="o">=</span> <span class="mi">32768</span>
<span class="k">def</span> <span class="nf">gen_hash</span><span class="p">(</span><span class="n">password</span><span class="p">,</span> <span class="n">salt</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
    <span class="n">salt</span> <span class="o">=</span> <span class="n">salt</span> <span class="ow">or</span> <span class="n">os</span><span class="o">.</span><span class="n">urandom</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span>
    <span class="n">comp</span> <span class="o">=</span> <span class="n">salt</span> <span class="o">+</span> <span class="n">password</span>
    <span class="n">out</span> <span class="o">=</span> <span class="n">sha256</span><span class="p">(</span><span class="n">comp</span><span class="p">)</span><span class="o">.</span><span class="n">digest</span><span class="p">()</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">xrange</span><span class="p">(</span><span class="n">PASSES</span><span class="o">-</span><span class="mi">1</span><span class="p">):</span>
        <span class="n">out</span> <span class="o">=</span> <span class="n">sha256</span><span class="p">(</span><span class="n">out</span> <span class="o">+</span> <span class="n">comp</span><span class="p">)</span><span class="o">.</span><span class="n">digest</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">salt</span><span class="p">,</span> <span class="n">out</span>

<span class="n">user</span> <span class="o">=</span> <span class="n">User</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s1">&#39;user@host.com&#39;</span><span class="p">)</span>
<span class="n">user</span><span class="o">.</span><span class="n">salt</span><span class="p">,</span> <span class="n">user</span><span class="o">.</span><span class="n">hash</span> <span class="o">=</span> <span class="n">gen_hash</span><span class="p">(</span><span class="n">password</span><span class="p">)</span>
<span class="n">user</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
<span class="c1"># session.commit() or session.flush() works too</span>
</pre></div>
</div>
</li>
<li><p class="first">Load and use the object later:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">user</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">get_by</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s1">&#39;user@host.com&#39;</span><span class="p">)</span>
<span class="n">at_gmail</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s1">&#39;@gmail.com&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
</pre></div>
</div>
</li>
</ol>
</div>
<div class="section" id="lua-support">
<h2>Lua support<a class="headerlink" href="#lua-support" title="Permalink to this headline">¶</a></h2>
<p>From version 0.25.0 and on, rom assumes that you are using Redis version 2.6
or later, which supports server-side Lua scripting. This allows for the
support of multiple unique column constraints without annoying race conditions
and retries. This also allows for the support of prefix, suffix, and pattern
matching on certain column types.</p>
<p>If you are using a version of Redis prior to 2.6, you should upgrade Redis. If
you are unable or unwilling to upgrade Redis, but you still wish to use rom,
you should call <code class="docutils literal notranslate"><span class="pre">rom._disable_lua_writes()</span></code>, which will prevent you from
using features that require Lua scripting support.</p>
</div>
<div class="section" id="expiring-models-ttls">
<h2>Expiring models/TTLs<a class="headerlink" href="#expiring-models-ttls" title="Permalink to this headline">¶</a></h2>
<p>There is a series of feature requests/bug reports/pull requests to add the
ability for rom to automatically delete and/or expire entity data stored in
Redis. This is a request that has been made (as of January 2016) 6 different
times.</p>
<p>Long story short: rom stores a bunch of data in secondary structures to make
querying fast. When a model “expires”, that data doesn’t get deleted. To
delete that data, you have to run a cleanup function that literally has to
scan over every entity in order to determine if the model had been expired. That
is a huge waste and is the antithesis of good design.</p>
<p>Instead, if you create a new <code class="docutils literal notranslate"><span class="pre">expire_at</span></code> float column with <code class="docutils literal notranslate"><span class="pre">index=True</span></code>,
the column can store when the entity is to expire. Then to expire the data, you
can use: <code class="docutils literal notranslate"><span class="pre">Model.query.filter(expire_at=(0,</span> <span class="pre">time.time())).limit(10)</span></code> to (for
example) get up to the 10 oldest entites that need to be expired.</p>
<p>Now, I know what you are thinking. You are thinking, “but I wish the data would
just go away on its own.” And I don’t disagree. But for that to happen, Redis
needs to grow Lua-script triggers, or you need to run a separate daemon to
periodically clean up left-over data. But … if you need to run a separate
daemon to clean up left-over data by scanning all of your rom entities,
wouldn’t it just be better/faster in every way to keep an explicit column and do
it efficiently? I think so, and you should too.</p>
<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Boolean</code><span class="sig-paren">(</span><em>required=False</em>, <em>default=&lt;object object&gt;</em>, <em>unique=False</em>, <em>index=False</em>, <em>keygen=None</em>, <em>prefix=False</em>, <em>suffix=False</em>, <em>keygen2=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>Used for boolean columns.</p>
<p>All standard arguments supported. See <code class="docutils literal notranslate"><span class="pre">Column</span></code> for details on supported
arguments.</p>
<p>All values passed in on creation are casted via bool(), with the exception
of None (which behaves as though the value was missing), and any existing
data in Redis is considered <code class="docutils literal notranslate"><span class="pre">False</span></code> if empty, and <code class="docutils literal notranslate"><span class="pre">True</span></code> otherwise.</p>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">Boolean</span><span class="p">()</span>
</pre></div>
</div>
<p>Queries via <code class="docutils literal notranslate"><span class="pre">MyModel.get_by(...)</span></code> and <code class="docutils literal notranslate"><span class="pre">MyModel.query.filter(...)</span></code> work
as expected when passed <code class="docutils literal notranslate"><span class="pre">True</span></code> or <code class="docutils literal notranslate"><span class="pre">False</span></code>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">these columns are not sortable by default.</p>
</div>
</dd></dl>

<dl class="function">
<dt>
<code class="descclassname">rom.</code><code class="descname">CASE_INSENSITIVE</code><span class="sig-paren">(</span><em>val</em><span class="sig-paren">)</span></dt>
<dd><p>Old alias for SIMPLE_CI</p>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">ClassProperty</code><span class="sig-paren">(</span><em>get</em>, <em>set=None</em>, <em>delete=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>Borrowed from: <a class="reference external" href="https://gist.github.com/josiahcarlson/1561563">https://gist.github.com/josiahcarlson/1561563</a></p>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Column</code><span class="sig-paren">(</span><em>required=False</em>, <em>default=&lt;object object&gt;</em>, <em>unique=False</em>, <em>index=False</em>, <em>keygen=None</em>, <em>prefix=False</em>, <em>suffix=False</em>, <em>keygen2=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>Column objects handle data conversion to/from strings, store metadata
about indices, etc. Note that these are “heavy” columns, in that whenever
data is read/written, it must go through descriptor processing. This is
primarily so that (for example) if you try to write a Decimal to a Float
column, you get an error the moment you try to do it, not some time later
when you try to save the object (though saving can still cause an error
during the conversion process).</p>
<p>Standard Arguments:</p>
<blockquote>
<div><ul class="simple">
<li><em>required</em> - determines whether this column is required on
creation</li>
<li><em>default</em> - a default value (either a callable or a simple value)
when this column is not provided</li>
<li><em>unique</em> - can be enabled on string, unicode, and integer columns, and
allows for required distinct column values (like an email address on
a User model)</li>
<li><em>index</em> - can be enabled on numeric, string, and unicode columns.
Will create a ZSET-based numeric index for numeric columns and a
“full word”-based search for string/unicode columns. If enabled
for other (or custom) columns, remember to provide the
<code class="docutils literal notranslate"><span class="pre">keygen</span></code> argument</li>
<li><em>keygen</em> - pass a function that takes your column’s value and
returns the data that you want to index (see the keygen docs for
what kinds of data to return)</li>
<li><em>keygen2</em> - pass a function that takes your column name and the dict
representing the current entity’s complete data - can be used for
creating multi-column indexes</li>
</ul>
</div></blockquote>
<p>String/Text arguments:</p>
<blockquote>
<div><ul class="simple">
<li><em>prefix</em> - can be enabled on any column that generates a list of
strings as a result of the default or passed <em>keygen</em> function, and
will allow the searching of prefix matches (autocomplete) over your
data. See <code class="docutils literal notranslate"><span class="pre">Query.startswith()</span></code> for details.</li>
<li><em>suffix</em> - can be enabled in the same contexts as <em>prefix</em> and
enables suffix matching over your data. Any individual string in the
returned data will be reversed (you need to make sure this makes
conceptual sense with your data) before being stored or used. See
<code class="docutils literal notranslate"><span class="pre">Query.endswith()</span></code> for details.</li>
</ul>
</div></blockquote>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">Enabling prefix or suffix matching on a column only makes
sense for columns defining a non-numeric <em>keygen</em> function.</p>
</div>
<p>Notes:</p>
<blockquote>
<div><ul class="simple">
<li>If you have disabled Lua support, you can only have at most one
unique column on each model</li>
<li><em>Unique</em> and <em>index</em> are not mutually exclusive</li>
<li>The <em>keygen</em> argument determines how index values are generated
from column data (with a reasonably sensible default for numeric
columns, and 2 convenient options for string/text columns)</li>
<li>If you set <em>required</em> to True, then you must have the column set
during object construction: <code class="docutils literal notranslate"><span class="pre">MyModel(col=val)</span></code></li>
<li>If <em>index</em> and <em>prefix</em>, or <em>index</em> and <em>suffix</em> are set, the same
keygen will be used for both the regular <em>index</em> as well as the
<em>prefix</em> and/or <em>suffix</em> searches</li>
<li>If <em>prefix</em> is set, you can perform pattern matches over your data.
See documention on <code class="docutils literal notranslate"><span class="pre">Query.like()</span></code> for details.</li>
<li>Pattern matching over data is only guaranteed to be valid or correct
for ANSI strings that do not include nulls, though we make an effort
to support unicode strings and strings with embedded nulls</li>
<li>Prefix, suffix, and pattern matching are performed within a Lua
script, so may have substantial execution time if there are a large
number of matching prefix or suffix entries</li>
<li>Whenever possible, pattern matching will attempt to use any
non-wildcard prefixes on the pattern to limit the items to be
scanned. A pattern starting with <code class="docutils literal notranslate"><span class="pre">?</span></code>, <code class="docutils literal notranslate"><span class="pre">*</span></code>, <code class="docutils literal notranslate"><span class="pre">+</span></code>, or <code class="docutils literal notranslate"><span class="pre">!</span></code> will
not be able to use any prefix, so will scan the entire index for
matches (aka: expensive)</li>
</ul>
</div></blockquote>
<p>There are 3 types of string indexes that rom currently supports:</p>
<blockquote>
<div><ul class="simple">
<li><em>SIMPLE</em>/<em>SIMPLE_CI</em> - sorting only with <code class="docutils literal notranslate"><span class="pre">query.order_by('x')</span></code> -
<a class="reference external" href="https://josiahcarlson.github.io/rom/util.html#rom.util.SIMPLE">https://josiahcarlson.github.io/rom/util.html#rom.util.SIMPLE</a></li>
<li><em>IDENTITY</em>/<em>IDENTITY_CI</em> - equality only with <code class="docutils literal notranslate"><span class="pre">query.filter(x=...)</span></code> -
<a class="reference external" href="https://josiahcarlson.github.io/rom/util.html#rom.util.IDENTITY">https://josiahcarlson.github.io/rom/util.html#rom.util.IDENTITY</a></li>
<li><em>FULL_TEXT</em> - bag of words inverted index for <code class="docutils literal notranslate"><span class="pre">query.filter(x=...)</span></code> -
<a class="reference external" href="https://josiahcarlson.github.io/rom/util.html#rom.util.FULL_TEXT">https://josiahcarlson.github.io/rom/util.html#rom.util.FULL_TEXT</a></li>
</ul>
</div></blockquote>
<p>To each of those 3 index types, you can further add a prefix/suffix index,
whose semantics are as follows:</p>
<blockquote>
<div><ul class="simple">
<li><em>prefix</em> - <code class="docutils literal notranslate"><span class="pre">query.startswith(column=pfix)</span></code> and <code class="docutils literal notranslate"><span class="pre">query.like(column='stuff?*')</span></code></li>
<li><em>suffix</em> - <code class="docutils literal notranslate"><span class="pre">query.endswith(column=sfix)</span></code></li>
<li><em>SIMPLE</em>/<em>SIMPLE_CI</em>/<em>IDENTITY</em>/<em>IDENTITY_CI</em> - <em>prefix</em>/<em>suffix</em> the
whole string case sensitive or insensitive</li>
<li><em>FULL_TEXT</em> - <em>prefix</em>/<em>suffix</em> on individual words parsed out of the
full text</li>
</ul>
</div></blockquote>
</dd></dl>

<dl class="exception">
<dt>
<em class="property">exception </em><code class="descclassname">rom.</code><code class="descname">ColumnError</code></dt>
<dd><p>Bases: <a class="reference internal" href="exceptions.html#rom.exceptions.ORMError" title="rom.exceptions.ORMError"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.exceptions.ORMError</span></code></a></p>
<p>Raised when your column definitions are not correct</p>
</dd></dl>

<dl class="exception">
<dt>
<em class="property">exception </em><code class="descclassname">rom.</code><code class="descname">DataRaceError</code></dt>
<dd><p>Bases: <a class="reference internal" href="exceptions.html#rom.exceptions.InvalidOperation" title="rom.exceptions.InvalidOperation"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.exceptions.InvalidOperation</span></code></a></p>
<p>Raised when more than one writer tries to update the same columns on the same entity</p>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Date</code><span class="sig-paren">(</span><em>required=False</em>, <em>default=&lt;object object&gt;</em>, <em>unique=False</em>, <em>index=False</em>, <em>keygen=None</em>, <em>prefix=False</em>, <em>suffix=False</em>, <em>keygen2=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>A date column.</p>
<p>All standard arguments supported. See <code class="docutils literal notranslate"><span class="pre">Column</span></code> for details on supported
arguments.</p>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">Date</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">DateTime</code><span class="sig-paren">(</span><em>required=False</em>, <em>default=&lt;object object&gt;</em>, <em>unique=False</em>, <em>index=False</em>, <em>keygen=None</em>, <em>prefix=False</em>, <em>suffix=False</em>, <em>keygen2=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>A datetime column.</p>
<p>All standard arguments supported. See <code class="docutils literal notranslate"><span class="pre">Column</span></code> for details on supported
arguments.</p>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">DateTime</span><span class="p">()</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">tzinfo objects are not stored</p>
</div>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Decimal</code><span class="sig-paren">(</span><em>required=False</em>, <em>default=&lt;object object&gt;</em>, <em>unique=False</em>, <em>index=False</em>, <em>keygen=None</em>, <em>prefix=False</em>, <em>suffix=False</em>, <em>keygen2=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>A Decimal-only numeric column (converts ints/longs into Decimals
automatically). Attempts to assign Python float will fail.</p>
<p>All standard arguments supported. See <code class="docutils literal notranslate"><span class="pre">Column</span></code> for details on supported
arguments.</p>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

<dl class="exception">
<dt>
<em class="property">exception </em><code class="descclassname">rom.</code><code class="descname">EntityDeletedError</code></dt>
<dd><p>Bases: <a class="reference internal" href="exceptions.html#rom.exceptions.InvalidOperation" title="rom.exceptions.InvalidOperation"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.exceptions.InvalidOperation</span></code></a></p>
<p>Raised when another writer deleted the entity from Redis; use .save(force=True) to re-save</p>
</dd></dl>

<dl class="function">
<dt>
<code class="descclassname">rom.</code><code class="descname">FULL_TEXT</code><span class="sig-paren">(</span><em>val</em><span class="sig-paren">)</span></dt>
<dd><p>This is a basic full-text index keygen function. Words are lowercased, split
by whitespace, and stripped of punctuation from both ends before an inverted
index is created for term searching.</p>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Float</code><span class="sig-paren">(</span><em>required=False</em>, <em>default=&lt;object object&gt;</em>, <em>unique=False</em>, <em>index=False</em>, <em>keygen=None</em>, <em>prefix=False</em>, <em>suffix=False</em>, <em>keygen2=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>Numeric column that supports integers and floats (values are turned into
floats on load from Redis).</p>
<p>All standard arguments supported. See <code class="docutils literal notranslate"><span class="pre">Column</span></code> for details on supported
arguments.</p>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">Float</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">ForeignModel</code><span class="sig-paren">(</span><em>fmodel</em>, <em>required=False</em>, <em>default=&lt;object object&gt;</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>This column allows for <code class="docutils literal notranslate"><span class="pre">rom</span></code> models to reference an instance of another
model from an unrelated ORM or otherwise.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">In order for this mechanism to work, the foreign model <em>must</em>
have an <code class="docutils literal notranslate"><span class="pre">id</span></code> attribute or property represents its primary key, and
<em>must</em> have a classmethod or staticmethod named <code class="docutils literal notranslate"><span class="pre">get()</span></code> that returns
the proper database entity.</p>
</div>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">ForeignModel</span><span class="p">(</span><span class="n">DjangoModel</span><span class="p">)</span>

<span class="n">dm</span> <span class="o">=</span> <span class="n">DjangoModel</span><span class="p">(</span><span class="n">col1</span><span class="o">=</span><span class="s1">&#39;foo&#39;</span><span class="p">)</span>
<span class="n">django</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">transaction</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>

<span class="n">x</span> <span class="o">=</span> <span class="n">MyModel</span><span class="p">(</span><span class="n">col</span><span class="o">=</span><span class="n">dm</span><span class="p">)</span>
<span class="n">x</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">GeneralIndex</code><span class="sig-paren">(</span><em>namespace</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>This class implements general indexing and search for the <code class="docutils literal notranslate"><span class="pre">rom</span></code> package.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">You probably don’t want to be calling this directly. Instead,
you should rely on the <code class="docutils literal notranslate"><span class="pre">Query</span></code> object returned from <code class="docutils literal notranslate"><span class="pre">Model.query</span></code> to
handle all of your query pre-processing.</p>
</div>
<p>Generally speaking, numeric indices use ZSETs, and text indices use SETs
built using an ‘inverted index’.</p>
<p>Say that we have words <code class="docutils literal notranslate"><span class="pre">hello</span> <span class="pre">world</span></code> in a column <code class="docutils literal notranslate"><span class="pre">c</span></code> on a model with
primary key <code class="docutils literal notranslate"><span class="pre">MyModel:1</span></code>. The member <code class="docutils literal notranslate"><span class="pre">1</span></code> will be added to SETs with
keys:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">MyModel</span><span class="p">:</span><span class="n">c</span><span class="p">:</span><span class="n">hello</span>
<span class="n">MyModel</span><span class="p">:</span><span class="n">c</span><span class="p">:</span><span class="n">world</span>
</pre></div>
</div>
<p>Text searching performs a sequence of intersections of SETs for the words
to be searched for.</p>
<p>Numeric range searching performs a sequence of intersections of ZSETs,
removing items outside the requested range after each intersection.</p>
<p>Searches will pre-sort intersections from smallest to largest SET/ZSET
prior to performing the search to improve performance.</p>
<p>Prefix, suffix, and pattern matching change this operation. Given a key
generated of <code class="docutils literal notranslate"><span class="pre">hello</span></code> on a column <code class="docutils literal notranslate"><span class="pre">c</span></code> on a model with primary key
<code class="docutils literal notranslate"><span class="pre">MyModel:1</span></code>, the member <code class="docutils literal notranslate"><span class="pre">hello\01</span></code> with score 0 will be added to a
ZSET with the key name <code class="docutils literal notranslate"><span class="pre">MyModel:c:pre</span></code> for the prefix/pattern index.
On a suffix index, the member <code class="docutils literal notranslate"><span class="pre">olleh\01</span></code> with score 0 will be added to
a ZSET with the key name <code class="docutils literal notranslate"><span class="pre">MyModel:c:suf</span></code>.</p>
<p>Prefix and suffix matches are excuted in Lua with a variant of the
autocomplete method described in Redis in Action. These methods ensure a
runtime proportional to the number of matched entries.</p>
<p>Pattern matching also uses a Lua script to scan over data in the prefix
index, exploiting prefixes in patterns if they exist.</p>
<dl class="method">
<dt>
<code class="descname">count</code><span class="sig-paren">(</span><em>conn</em>, <em>filters</em><span class="sig-paren">)</span></dt>
<dd><p>Returns the count of the items that match the provided filters.</p>
<p>For the meaning of what the <code class="docutils literal notranslate"><span class="pre">filters</span></code> argument means, see the
<code class="docutils literal notranslate"><span class="pre">.search()</span></code> method docs.</p>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">search</code><span class="sig-paren">(</span><em>conn</em>, <em>filters</em>, <em>order_by</em>, <em>offset=None</em>, <em>count=None</em>, <em>timeout=None</em><span class="sig-paren">)</span></dt>
<dd><p>Search for model ids that match the provided filters.</p>
<p>Arguments:</p>
<blockquote>
<div><ul>
<li><p class="first"><em>filters</em> - A list of filters that apply to the search of one of
the following two forms:</p>
<blockquote>
<div><ol class="arabic simple">
<li><code class="docutils literal notranslate"><span class="pre">'column:string'</span></code> - a plain string will match a word in a
text search on the column</li>
</ol>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Read the documentation about the <code class="docutils literal notranslate"><span class="pre">Query</span></code> object
for what is actually passed during text search</p>
</div>
<ol class="arabic simple" start="2">
<li><code class="docutils literal notranslate"><span class="pre">('column',</span> <span class="pre">min,</span> <span class="pre">max)</span></code> - a numeric column range search,
between min and max (inclusive by default)</li>
</ol>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Read the documentation about the <code class="docutils literal notranslate"><span class="pre">Query</span></code> object
for information about open-ended ranges</p>
</div>
<ol class="arabic simple" start="3">
<li><code class="docutils literal notranslate"><span class="pre">['column:string1',</span> <span class="pre">'column:string2']</span></code> - will match any
of the provided words in a text search on the column</li>
<li><code class="docutils literal notranslate"><span class="pre">Prefix('column',</span> <span class="pre">'prefix')</span></code> - will match prefixes of
words in a text search on the column</li>
<li><code class="docutils literal notranslate"><span class="pre">Suffix('column',</span> <span class="pre">'suffix')</span></code> - will match suffixes of
words in a text search on the column</li>
<li><code class="docutils literal notranslate"><span class="pre">Pattern('column',</span> <span class="pre">'pattern')</span></code> - will match patterns over
words in a text search on the column</li>
</ol>
</div></blockquote>
</li>
<li><p class="first"><em>order_by</em> - A string that names the numeric column by which to
sort the results by. Prefixing with ‘-‘ will return results in
descending order</p>
</li>
</ul>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">While you can technically pass a non-numeric index as an
<em>order_by</em> clause, the results will basically be to order the
results by string comparison of the ids (10 will come before 2).</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you omit the <code class="docutils literal notranslate"><span class="pre">order_by</span></code> argument, results will be
ordered by the last filter. If the last filter was a text
filter, see the previous note. If the last filter was numeric,
then results will be ordered by that result.</p>
</div>
<ul class="simple">
<li><em>offset</em> - A numeric starting offset for results</li>
<li><em>count</em> - The maximum number of results to return from the query</li>
</ul>
</div></blockquote>
</dd></dl>

</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">GeoIndex</code><span class="sig-paren">(</span><em>name</em>, <em>callback</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">tuple</span></code></p>
<dl class="attribute">
<dt>
<code class="descname">callback</code></dt>
<dd><p>Alias for field number 1</p>
</dd></dl>

<dl class="attribute">
<dt>
<code class="descname">name</code></dt>
<dd><p>Alias for field number 0</p>
</dd></dl>

</dd></dl>

<dl class="function">
<dt>
<code class="descclassname">rom.</code><code class="descname">IDENTITY</code><span class="sig-paren">(</span><em>val</em><span class="sig-paren">)</span></dt>
<dd><p>This is a basic “equality” index keygen, primarily meant to be used for
things like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Model</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">col</span><span class="o">=</span><span class="s1">&#39;value&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>Where <code class="docutils literal notranslate"><span class="pre">FULL_TEXT</span></code> would transform a sentence like “A Simple Sentence” into
an inverted index searchable by the words “a”, “simple”, and/or “sentence”,
<code class="docutils literal notranslate"><span class="pre">IDENTITY</span></code> will only be searchable by the orginal full sentence with the
same capitalization - “A Simple Sentence”. See <code class="docutils literal notranslate"><span class="pre">IDENTITY_CI</span></code> for the
same function, only case-insensitive.</p>
</dd></dl>

<dl class="function">
<dt>
<code class="descclassname">rom.</code><code class="descname">IDENTITY_CI</code><span class="sig-paren">(</span><em>val</em><span class="sig-paren">)</span></dt>
<dd><p>Case-insensitive version of IDENTITY</p>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">IndexOnly</code><span class="sig-paren">(</span><em>column=None</em>, <em>keygen=None</em>, <em>prefix=False</em>, <em>suffix=False</em>, <em>keygen2=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>This column doesn’t actually store data, except in indexes for other
columns. Say, for example, you have an email text field that you want to
be unique, look-up by identity, but also be parsed out for a sort of
address-book index. Normally that would suck. But not with <code class="docutils literal notranslate"><span class="pre">IndexOnly()</span></code>
columns! Data set on this attribute will raise an exception, and will be
silently ignored (and potentially deleted) if already stored in Redis.</p>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">re</span>
<span class="k">def</span> <span class="nf">split_email</span><span class="p">(</span><span class="n">val</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">val</span><span class="p">:</span>
        <span class="k">return</span> <span class="nb">set</span><span class="p">(</span><span class="nb">filter</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;[^\w]&#39;</span><span class="p">,</span> <span class="n">val</span><span class="o">.</span><span class="n">lower</span><span class="p">())))</span>

<span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">email</span> <span class="o">=</span> <span class="n">Text</span><span class="p">(</span><span class="n">unique</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
    <span class="n">elookup</span> <span class="o">=</span> <span class="n">IndexOnly</span><span class="p">(</span><span class="s1">&#39;email&#39;</span><span class="p">,</span> <span class="n">keygen</span><span class="o">=</span><span class="n">split_email</span><span class="p">)</span>

<span class="n">MyModel</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s1">&#39;user@host.com&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
<span class="n">MyModel</span><span class="o">.</span><span class="n">get_by</span><span class="p">(</span><span class="n">elookup</span><span class="o">=</span><span class="s1">&#39;user&#39;</span><span class="p">)</span>
<span class="n">MyModel</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">elookup</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;user&#39;</span><span class="p">,</span> <span class="s1">&#39;host&#39;</span><span class="p">])</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">I’ve been using a variation of this internally for some of my
own work, and I thought I’d release it as a convenience column.</p>
</div>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Integer</code><span class="sig-paren">(</span><em>required=False</em>, <em>default=&lt;object object&gt;</em>, <em>unique=False</em>, <em>index=False</em>, <em>keygen=None</em>, <em>prefix=False</em>, <em>suffix=False</em>, <em>keygen2=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>Used for integer numeric columns.</p>
<p>All standard arguments supported. See <code class="docutils literal notranslate"><span class="pre">Column</span></code> for details on supported
arguments.</p>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">Integer</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

<dl class="exception">
<dt>
<em class="property">exception </em><code class="descclassname">rom.</code><code class="descname">InvalidColumnValue</code></dt>
<dd><p>Bases: <a class="reference internal" href="exceptions.html#rom.exceptions.ColumnError" title="rom.exceptions.ColumnError"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.exceptions.ColumnError</span></code></a></p>
<p>Raised when you attempt to pass a primary key on entity creation or when data assigned to a column is the wrong type</p>
</dd></dl>

<dl class="exception">
<dt>
<em class="property">exception </em><code class="descclassname">rom.</code><code class="descname">InvalidOperation</code></dt>
<dd><p>Bases: <a class="reference internal" href="exceptions.html#rom.exceptions.ORMError" title="rom.exceptions.ORMError"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.exceptions.ORMError</span></code></a></p>
<p>Raised when trying to delete or modify a column that cannot be deleted or modified</p>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Json</code><span class="sig-paren">(</span><em>required=False</em>, <em>default=&lt;object object&gt;</em>, <em>unique=False</em>, <em>index=False</em>, <em>keygen=None</em>, <em>prefix=False</em>, <em>suffix=False</em>, <em>keygen2=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>Allows for more complicated nested structures as attributes.</p>
<p>All standard arguments supported. The <code class="docutils literal notranslate"><span class="pre">keygen</span></code> argument must be provided
if <code class="docutils literal notranslate"><span class="pre">index</span></code> is <code class="docutils literal notranslate"><span class="pre">True</span></code>.</p>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">Json</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">ManyToOne</code><span class="sig-paren">(</span><em>ftable</em>, <em>on_delete=&lt;object object&gt;</em>, <em>required=False</em>, <em>default=&lt;object object&gt;</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>This ManyToOne column allows for one model to reference another model.
While a ManyToOne column does not require a reverse OneToMany column
(which will return a list of models that reference it via a ManyToOne), it
is generally seen as being useful to have both sides of the relationship
defined.</p>
<p>Aside from the name of the other model, only the <code class="docutils literal notranslate"><span class="pre">required</span></code> and
<code class="docutils literal notranslate"><span class="pre">default</span></code> arguments are accepted.</p>
<p>Four arguments are supported:</p>
<blockquote>
<div><ul class="simple">
<li><em>ftable</em> - the name of the other model (required argument)</li>
<li><dl class="first docutils">
<dt><em>on_delete</em> - how to handle foreign key references on delete,</dt>
<dd>supported options include: ‘no action’, ‘restrict’, ‘cascade’
‘set default’, and ‘set null’ (required argument)</dd>
</dl>
</li>
<li><em>required</em> - determines whether this column is required on
creation</li>
<li><em>default</em> - a default value (either a callable or a simple value)
when this column is not provided</li>
</ul>
</div></blockquote>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">ManyToOne</span><span class="p">(</span><span class="s1">&#39;OtherModelName&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">All <code class="docutils literal notranslate"><span class="pre">ManyToOne</span></code> columns are indexed numerically, which means
that you can find entities referencing specific id ranges or even sort by
referenced ids.</p>
</div>
</dd></dl>

<dl class="exception">
<dt>
<em class="property">exception </em><code class="descclassname">rom.</code><code class="descname">MissingColumn</code></dt>
<dd><p>Bases: <a class="reference internal" href="exceptions.html#rom.exceptions.ColumnError" title="rom.exceptions.ColumnError"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.exceptions.ColumnError</span></code></a></p>
<p>Raised when a model has a required column, but it is not provided on construction</p>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Model</code><span class="sig-paren">(</span><em>**kwargs</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>This is the base class for all models. You subclass from this base Model
in order to create a model with columns. As an example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">email_address</span> <span class="o">=</span> <span class="n">String</span><span class="p">(</span><span class="n">required</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">unique</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
    <span class="n">salt</span> <span class="o">=</span> <span class="n">String</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
    <span class="nb">hash</span> <span class="o">=</span> <span class="n">String</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
    <span class="n">created_at</span> <span class="o">=</span> <span class="n">Float</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p>Which can then be used like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">user</span> <span class="o">=</span> <span class="n">User</span><span class="p">(</span><span class="n">email_addrss</span><span class="o">=</span><span class="s1">&#39;user@domain.com&#39;</span><span class="p">)</span>
<span class="n">user</span><span class="o">.</span><span class="n">save</span><span class="p">()</span> <span class="c1"># session.commit() or session.flush() works too</span>
<span class="n">user</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">get_by</span><span class="p">(</span><span class="n">email_address</span><span class="o">=</span><span class="s1">&#39;user@domain.com&#39;</span><span class="p">)</span>
<span class="n">user</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="n">users</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">get</span><span class="p">([</span><span class="mi">2</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">])</span>
</pre></div>
</div>
<p>To perform arbitrary queries on entities involving the indices that you
defined (by passing <code class="docutils literal notranslate"><span class="pre">index=True</span></code> on column creation), you access the
<code class="docutils literal notranslate"><span class="pre">.query</span></code> class property on the model:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">query</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">query</span>
<span class="n">query</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">created_at</span><span class="o">=</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span><span class="o">-</span><span class="mi">86400</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()))</span>
<span class="n">users</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">execute</span><span class="p">()</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">You can perform single or chained queries against any/all columns
that were defined with <code class="docutils literal notranslate"><span class="pre">index=True</span></code>.</p>
</div>
<p><strong>Composite/multi-column unique constraints</strong></p>
<p>As of version 0.28.0 and later, rom supports the ability for you to have a
unique constraint involving multiple columns. Individual columns can be
defined unique by passing the ‘unique=True’ specifier during column
definition as always.</p>
<p>The attribute <code class="docutils literal notranslate"><span class="pre">unique_together</span></code> defines those groups of columns that when
taken together must be unique for <code class="docutils literal notranslate"><span class="pre">.save()</span></code> to complete successfully.
This will work almost exactly the same as Django’s <code class="docutils literal notranslate"><span class="pre">unique_together</span></code>, and
is comparable to SQLAlchemy’s <code class="docutils literal notranslate"><span class="pre">UniqueConstraint()</span></code>.</p>
<p>Usage:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">UniquePosition</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">x</span> <span class="o">=</span> <span class="n">Integer</span><span class="p">()</span>
    <span class="n">y</span> <span class="o">=</span> <span class="n">Integer</span><span class="p">()</span>

    <span class="n">unique_together</span> <span class="o">=</span> <span class="p">[</span>
        <span class="p">(</span><span class="s1">&#39;x&#39;</span><span class="p">,</span> <span class="s1">&#39;y&#39;</span><span class="p">),</span>
    <span class="p">]</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If one or more of the column values on an entity that is part of a
unique constrant is None in Python, the unique constraint won’t apply.
This is the typical behavior of nulls in unique constraints inside both
MySQL and Postgres.</p>
</div>
<dl class="method">
<dt>
<code class="descname">copy</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Creates a shallow copy of the given entity (any entities that can be
retrieved from a OneToMany relationship will not be copied).</p>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">delete</code><span class="sig-paren">(</span><em>**kwargs</em><span class="sig-paren">)</span></dt>
<dd><p>Deletes the entity immediately. Also performs any on_delete operations
specified as part of column definitions.</p>
</dd></dl>

<dl class="classmethod">
<dt>
<em class="property">classmethod </em><code class="descname">does_not_endwith</code><span class="sig-paren">(</span><em>attr</em>, <em>values</em>, <em>blocksize=100</em><span class="sig-paren">)</span></dt>
<dd><p>This iterates over all entities with an attribute that does not end
with the provided values. This is only available to models with a suffix
index on the given attribute; values must be normalized the same as with
the indexed inputs for this to work properly (lowercased, etc.).</p>
<dl class="docutils">
<dt>Args:</dt>
<dd><ul class="first last simple">
<li><em>attr</em> - name of the attribute/column on the entity.</li>
<li><em>values</em> - list of values to exclude.</li>
</ul>
</dd>
</dl>
<p>This method will auto-forget items from the session after yielding them,
so if you want to <em>change</em> data, you’ll have to handle saving and
deleting outside of the session.</p>
<dl class="docutils">
<dt>..note: values &lt;= 7 characters long will be fast, values &gt;= 8 characters</dt>
<dd>will require round trips and will be substantially slower.</dd>
</dl>
</dd></dl>

<dl class="classmethod">
<dt>
<em class="property">classmethod </em><code class="descname">does_not_startwith</code><span class="sig-paren">(</span><em>attr</em>, <em>values</em>, <em>blocksize=100</em><span class="sig-paren">)</span></dt>
<dd><p>This iterates over all entities with an attribute that does not start
with the provided values. This is only available to models with a prefix
index on the given attribute; values must be normalized the same as with
the indexed inputs for this to work properly (lowercased, etc.).</p>
<dl class="docutils">
<dt>Args:</dt>
<dd><ul class="first last simple">
<li><em>attr</em> - name of the attribute/column on the entity.</li>
<li><em>values</em> - list of values to exclude.</li>
</ul>
</dd>
</dl>
<p>This method will auto-forget items from the session after yielding them,
so if you want to <em>change</em> data, you’ll have to handle saving and
deleting outside of the session.</p>
<dl class="docutils">
<dt>..note: values &lt;= 7 characters long will be fast, values &gt;= 8 characters</dt>
<dd>will require round trips and will be substantially slower.</dd>
</dl>
</dd></dl>

<dl class="classmethod">
<dt>
<em class="property">classmethod </em><code class="descname">get</code><span class="sig-paren">(</span><em>ids</em><span class="sig-paren">)</span></dt>
<dd><p>Will fetch one or more entities of this type from the session or
Redis.</p>
<p>Used like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">MyModel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="n">MyModel</span><span class="o">.</span><span class="n">get</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">])</span>
</pre></div>
</div>
<p>Passing a list or a tuple will return multiple entities, in the same
order that the ids were passed.</p>
</dd></dl>

<dl class="classmethod">
<dt>
<em class="property">classmethod </em><code class="descname">get_by</code><span class="sig-paren">(</span><em>**kwargs</em><span class="sig-paren">)</span></dt>
<dd><p>This method offers a simple query method for fetching entities of this
type via attribute numeric ranges (such columns must be <code class="docutils literal notranslate"><span class="pre">indexed</span></code>),
or via <code class="docutils literal notranslate"><span class="pre">unique</span></code> columns.</p>
<p>Some examples:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">user</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">get_by</span><span class="p">(</span><span class="n">email_address</span><span class="o">=</span><span class="s1">&#39;user@domain.com&#39;</span><span class="p">)</span>
<span class="c1"># gets up to 25 users created in the last 24 hours</span>
<span class="n">users</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">get_by</span><span class="p">(</span>
    <span class="n">created_at</span><span class="o">=</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span><span class="o">-</span><span class="mi">86400</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()),</span>
    <span class="n">_limit</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">25</span><span class="p">))</span>
</pre></div>
</div>
<p>Optional keyword-only arguments:</p>
<blockquote>
<div><ul class="simple">
<li><em>_limit</em> - A 2-tuple of (offset, count) that can be used to
paginate or otherwise limit results returned by a numeric range
query</li>
<li><em>_numeric</em> - An optional boolean defaulting to False that forces
the use of a numeric index for <code class="docutils literal notranslate"><span class="pre">.get_by(col=val)</span></code> queries even
when <code class="docutils literal notranslate"><span class="pre">col</span></code> has an existing unique index</li>
</ul>
</div></blockquote>
<p>If you would like to make queries against multiple columns or with
multiple criteria, look into the Model.query class property.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">rom will attempt to use a unique index first, then a numeric
index if there was no unique index. You can explicitly tell rom to
only use the numeric index by using <code class="docutils literal notranslate"><span class="pre">.get_by(...,</span> <span class="pre">_numeric=True)</span></code>.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Ranged queries with <cite>get_by(col=(start, end))</cite> will only work
with columns that use a numeric index.</p>
</div>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">save</code><span class="sig-paren">(</span><em>full=False</em>, <em>force=False</em><span class="sig-paren">)</span></dt>
<dd><p>Saves the current entity to Redis. Will only save changed data by
default, but you can force a full save by passing <code class="docutils literal notranslate"><span class="pre">full=True</span></code>.</p>
<p>If the underlying entity was deleted and you want to re-save the entity,
you can pass <code class="docutils literal notranslate"><span class="pre">force=True</span></code> to force a full re-save of the entity.</p>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">to_dict</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Returns a copy of all data assigned to columns in this entity. Useful
for returning items to JSON-enabled APIs. If you want to copy an
entity, you should look at the <code class="docutils literal notranslate"><span class="pre">.copy()</span></code> method.</p>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">transfer</code><span class="sig-paren">(</span><em>other</em>, <em>attr</em>, <em>value</em>, <em>txn_model</em>, <em>txn_attr</em>, <em>decimal_places=0</em>, <em>refresh_entities=True</em>, <em>refresh_index=True</em><span class="sig-paren">)</span></dt>
<dd><p>Transfer some numeric value from one entity to another.</p>
<p>This can (for example) be used to transfer money as part of an in-game
transaction, or other sort of value transfer.</p>
<blockquote>
<div><ul class="simple">
<li><em>other</em> - the other entity you would like to participate in this
transaction (must both have the same db connection)</li>
<li><em>attr</em> - the name of the attribute to transfer value on</li>
<li><em>value</em> - the value to transfer (rounded to <code class="docutils literal notranslate"><span class="pre">decimal_places</span></code>)</li>
<li><em>txn_model</em> - the entity that represents the value transfer to
perform (must have the same db connection as <code class="docutils literal notranslate"><span class="pre">self</span></code>, and <code class="docutils literal notranslate"><span class="pre">other</span></code>)</li>
<li><em>txn_attr</em> - the attribute on the entity that represents if the
value has been transferred</li>
<li><em>decimal_places</em> - the number of decimal places to the right of the
decimal to round to inside Redis / Lua; note that for values <code class="docutils literal notranslate"><span class="pre">&gt;0</span></code>,
this <em>will</em> introduce binary/decimal rounding problems; so small
epsilon credit may go away, and you will want to explicitly round on
the client on read + display. Or better yet; stick to integers.</li>
<li><em>refresh_entities</em> - will refresh the entity data on transfer if
<code class="docutils literal notranslate"><span class="pre">True</span></code>-ish</li>
<li><em>refresh_index</em> - will refresh the update any relevant indexs after
the transfer, if <code class="docutils literal notranslate"><span class="pre">True</span></code>-ish; implies <code class="docutils literal notranslate"><span class="pre">refresh_entities</span></code></li>
</ul>
</div></blockquote>
<dl class="docutils">
<dt>..warning: This doesn’t magically create more bits for you. Values in</dt>
<dd>Redis are either stored as up-to 64 bit integers (0 decimal places) or
64 bit doubles with 53 bits of precision. For doubles, that means
15-16 decimal digits. For 64 bit integers, that is 19+ digits, but
only integers. So if you want to maximize both precision, and your
range of values for “gold”, “points”, “experience”, “value”, etc.; use
your smallest denomination as your 1, and divmod on the client for
display if you need to.</dd>
</dl>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">update</code><span class="sig-paren">(</span><em>*args</em>, <em>**kwargs</em><span class="sig-paren">)</span></dt>
<dd><p>Updates multiple attributes in a model. If <code class="docutils literal notranslate"><span class="pre">args</span></code> are provided, this
method will assign attributes in the order returned by
<code class="docutils literal notranslate"><span class="pre">list(self._columns)</span></code> until one or both are exhausted.</p>
<p>If <code class="docutils literal notranslate"><span class="pre">kwargs</span></code> are provided, this method will assign attributes to the
names provided, after <code class="docutils literal notranslate"><span class="pre">args</span></code> have been processed.</p>
</dd></dl>

</dd></dl>

<dl class="exception">
<dt>
<em class="property">exception </em><code class="descclassname">rom.</code><code class="descname">ORMError</code></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
<p>Base class for all ORM-related errors</p>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">OneToMany</code><span class="sig-paren">(</span><em>ftable</em>, <em>column=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>OneToMany columns do not actually store any information. They rely on a
properly defined reverse ManyToOne column on the referenced model in order
to be able to fetch a list of referring entities.</p>
<p>Two arguments are supported:</p>
<blockquote>
<div><ul class="simple">
<li><em>ftable</em> - the name of the other model</li>
<li><dl class="first docutils">
<dt><em>column</em> - the attribute on the other model with the reference to</dt>
<dd>this column, required if the foreign model has multiple columns
referencing this model with OneToOne or ManyToOne columns</dd>
</dl>
</li>
</ul>
</div></blockquote>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">OneToMany</span><span class="p">(</span><span class="s1">&#39;OtherModelName&#39;</span><span class="p">)</span>
    <span class="n">ocol</span> <span class="o">=</span> <span class="n">OneToMany</span><span class="p">(</span><span class="s1">&#39;ModelName&#39;</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">OneToOne</code><span class="sig-paren">(</span><em>ftable</em>, <em>on_delete=&lt;object object&gt;</em>, <em>required=False</em>, <em>default=&lt;object object&gt;</em>, <em>unique=False</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.ManyToOne" title="rom.columns.ManyToOne"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.ManyToOne</span></code></a></p>
<p>This OneToOne column allows for one model to reference another model.
A OneToOne column does not require a reverse OneToOne column, and provides
<code class="docutils literal notranslate"><span class="pre">on_delete</span></code> behavior.</p>
<p>Five arguments are supported:</p>
<blockquote>
<div><ul class="simple">
<li><em>ftable</em> - the name of the other model (required argument)</li>
<li><dl class="first docutils">
<dt><em>on_delete</em> - how to handle foreign key references on delete,</dt>
<dd>supported options include: ‘no action’, ‘restrict’, ‘cascade’
‘set default’, and ‘set null’ (required argument)</dd>
</dl>
</li>
<li><em>required</em> - determines whether this column is required on
creation</li>
<li><em>default</em> - a default value (either a callable or a simple value)
when this column is not provided</li>
<li><dl class="first docutils">
<dt><em>unique</em> - whether or not the referenced entity must be a unique</dt>
<dd>reference</dd>
</dl>
</li>
</ul>
</div></blockquote>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">OneToOne</span><span class="p">(</span><span class="s1">&#39;OtherModelName&#39;</span><span class="p">,</span> <span class="s1">&#39;no action&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">All <code class="docutils literal notranslate"><span class="pre">OneToOne</span></code> columns are indexed numerically, which means
that you can find entities referencing specific id ranges or even sort by
referenced ids.</p>
</div>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Pattern</code><span class="sig-paren">(</span><em>attr</em>, <em>pattern</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">tuple</span></code></p>
<dl class="attribute">
<dt>
<code class="descname">attr</code></dt>
<dd><p>Alias for field number 0</p>
</dd></dl>

<dl class="attribute">
<dt>
<code class="descname">pattern</code></dt>
<dd><p>Alias for field number 1</p>
</dd></dl>

</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Prefix</code><span class="sig-paren">(</span><em>attr</em>, <em>prefix</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">tuple</span></code></p>
<dl class="attribute">
<dt>
<code class="descname">attr</code></dt>
<dd><p>Alias for field number 0</p>
</dd></dl>

<dl class="attribute">
<dt>
<code class="descname">prefix</code></dt>
<dd><p>Alias for field number 1</p>
</dd></dl>

</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">PrimaryKey</code><span class="sig-paren">(</span><em>index=False</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>This is a primary key column, used when you want the primary key to be
named something other than ‘id’. If you omit a PrimaryKey column on your
Model classes, one will be automatically created for you.</p>
<p>Only the <code class="docutils literal notranslate"><span class="pre">index</span></code> argument will be used. You may want to enable indexing
on this column if you want to be able to perform queries and sort the
results by primary key.</p>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="nb">id</span> <span class="o">=</span> <span class="n">PrimaryKey</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Query</code><span class="sig-paren">(</span><em>model</em>, <em>filters=()</em>, <em>order_by=None</em>, <em>limit=None</em>, <em>select=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>This is a query object. It behaves a lot like other query objects. Every
operation performed on Query objects returns a new Query object. The old
Query object <em>does not</em> have any updated filters.</p>
<dl class="method">
<dt>
<code class="descname">all</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Alias for <code class="docutils literal notranslate"><span class="pre">execute()</span></code>.</p>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">cached_result</code><span class="sig-paren">(</span><em>timeout</em><span class="sig-paren">)</span></dt>
<dd><p>This will execute the query, returning the key where a ZSET of your
results will be stored for pagination, further operations, etc.</p>
<p>The timeout must be a positive integer number of seconds for which to
set the expiration time on the key (this is to ensure that any cached
query results are eventually deleted, unless you make the explicit
step to use the PERSIST command).</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Limit clauses are ignored and not passed.</p>
</div>
<p>Usage:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ukey</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s1">&#39;@gmail.com&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">cached_result</span><span class="p">(</span><span class="mi">30</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">xrange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">conn</span><span class="o">.</span><span class="n">zcard</span><span class="p">(</span><span class="n">ukey</span><span class="p">),</span> <span class="mi">100</span><span class="p">):</span>
    <span class="c1"># refresh the expiration</span>
    <span class="n">conn</span><span class="o">.</span><span class="n">expire</span><span class="p">(</span><span class="n">ukey</span><span class="p">,</span> <span class="mi">30</span><span class="p">)</span>
    <span class="n">users</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">conn</span><span class="o">.</span><span class="n">zrange</span><span class="p">(</span><span class="n">ukey</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">i</span><span class="o">+</span><span class="mi">99</span><span class="p">))</span>
    <span class="o">...</span>
</pre></div>
</div>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">count</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Will return the total count of the objects that match the specified
filters.:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># counts the number of users created in the last 24 hours</span>
<span class="n">User</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">created_at</span><span class="o">=</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span><span class="o">-</span><span class="mi">86400</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()))</span><span class="o">.</span><span class="n">count</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">delete</code><span class="sig-paren">(</span><em>blocksize=100</em><span class="sig-paren">)</span></dt>
<dd><p>Will delete the entities that match at the time the query is executed.</p>
<p>Used like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">MyModel</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">email</span><span class="o">=...</span><span class="p">)</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="n">MyModel</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s1">&#39;@host.com&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
</pre></div>
</div>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">can’t be used on models on either side of a <code class="docutils literal notranslate"><span class="pre">OneToMany</span></code>,
<code class="docutils literal notranslate"><span class="pre">ManyToOne</span></code>, or <code class="docutils literal notranslate"><span class="pre">OneToOne</span></code> relationship.</p>
</div>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">endswith</code><span class="sig-paren">(</span><em>**kwargs</em><span class="sig-paren">)</span></dt>
<dd><p>When provided with keyword arguments of the form <code class="docutils literal notranslate"><span class="pre">col=suffix</span></code>, this
will limit the entities returned to those that have a word with the
provided suffix in the specified column(s). This requires that the
<code class="docutils literal notranslate"><span class="pre">suffix=True</span></code> option was provided during column definition.</p>
<p>Usage:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">User</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s1">&#39;@gmail.com&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">execute</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">execute</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Actually executes the query, returning any entities that match the
filters, ordered by the specified ordering (if any), limited by any
earlier limit calls.</p>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">filter</code><span class="sig-paren">(</span><em>**kwargs</em><span class="sig-paren">)</span></dt>
<dd><p>Only columns/attributes that have been specified as having an index with
the <code class="docutils literal notranslate"><span class="pre">index=True</span></code> option on the column definition can be filtered with
this method. Prefix, suffix, and pattern match filters must be provided
using the <code class="docutils literal notranslate"><span class="pre">.startswith()</span></code>, <code class="docutils literal notranslate"><span class="pre">.endswith()</span></code>, and the <code class="docutils literal notranslate"><span class="pre">.like()</span></code>
methods on the query object, respectively. Geo location queries should
be performed using the <code class="docutils literal notranslate"><span class="pre">.near()</span></code> method.</p>
<p>Filters should be of the form:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># for numeric ranges, use None for open-ended ranges</span>
<span class="n">attribute</span><span class="o">=</span><span class="p">(</span><span class="nb">min</span><span class="p">,</span> <span class="nb">max</span><span class="p">)</span>

<span class="c1"># you can also query for equality by passing a single number</span>
<span class="n">attribute</span><span class="o">=</span><span class="n">value</span>

<span class="c1"># for string searches, passing a plain string will require that</span>
<span class="c1"># string to be in the index as a literal</span>
<span class="n">attribute</span><span class="o">=</span><span class="n">string</span>

<span class="c1"># to perform an &#39;or&#39; query on strings, you can pass a list of</span>
<span class="c1"># strings</span>
<span class="n">attribute</span><span class="o">=</span><span class="p">[</span><span class="n">string1</span><span class="p">,</span> <span class="n">string2</span><span class="p">]</span>
</pre></div>
</div>
<p>As an example, the following will return entities that have both
<code class="docutils literal notranslate"><span class="pre">hello</span></code> and <code class="docutils literal notranslate"><span class="pre">world</span></code> in the <code class="docutils literal notranslate"><span class="pre">String</span></code> column <code class="docutils literal notranslate"><span class="pre">scol</span></code> and has a
<code class="docutils literal notranslate"><span class="pre">Numeric</span></code> column <code class="docutils literal notranslate"><span class="pre">ncol</span></code> with value between 2 and 10 (including the
endpoints):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">results</span> <span class="o">=</span> <span class="n">MyModel</span><span class="o">.</span><span class="n">query</span> \
    <span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">scol</span><span class="o">=</span><span class="s1">&#39;hello&#39;</span><span class="p">)</span> \
    <span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">scol</span><span class="o">=</span><span class="s1">&#39;world&#39;</span><span class="p">)</span> \
    <span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">ncol</span><span class="o">=</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">10</span><span class="p">))</span> \
    <span class="o">.</span><span class="n">all</span><span class="p">()</span>
</pre></div>
</div>
<p>If you only want to match a single value as part of your range query,
you can pass an integer, float, or Decimal object by itself, similar
to the <code class="docutils literal notranslate"><span class="pre">Model.get_by()</span></code> method:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">results</span> <span class="o">=</span> <span class="n">MyModel</span><span class="o">.</span><span class="n">query</span> \
    <span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">ncol</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span> \
    <span class="o">.</span><span class="n">execute</span><span class="p">()</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Trying to use a range query <cite>attribute=(min, max)</cite> on indexed
string columns won’t return any results.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">This method only filters columns that have been defined with
<code class="docutils literal notranslate"><span class="pre">index=True</span></code>.</p>
</div>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">first</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Returns only the first result from the query, if any.</p>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">iter_result</code><span class="sig-paren">(</span><em>timeout=30</em>, <em>pagesize=100</em>, <em>no_hscan=False</em><span class="sig-paren">)</span></dt>
<dd><p>Iterate over the results of your query instead of getting them all with
<cite>.all()</cite>. Will only perform a single query. If you expect that your
processing will take more than 30 seconds to process 100 items, you
should pass <cite>timeout</cite> and <cite>pagesize</cite> to reflect an appropriate timeout
and page size to fetch at once.</p>
<p>Usage:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">user</span> <span class="ow">in</span> <span class="n">User</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s1">&#39;@gmail.com&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">iter_result</span><span class="p">():</span>
    <span class="c1"># do something with user</span>
    <span class="o">...</span>
</pre></div>
</div>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">like</code><span class="sig-paren">(</span><em>**kwargs</em><span class="sig-paren">)</span></dt>
<dd><p>When provided with keyword arguments of the form <code class="docutils literal notranslate"><span class="pre">col=pattern</span></code>, this
will limit the entities returned to those that include the provided
pattern. Note that ‘like’ queries require that the <code class="docutils literal notranslate"><span class="pre">prefix=True</span></code>
option must have been provided as part of the column definition.</p>
<p>Patterns allow for 4 wildcard characters, whose semantics are as
follows:</p>
<blockquote>
<div><ul class="simple">
<li><em>?</em> - will match 0 or 1 of any character</li>
<li><em>*</em> - will match 0 or more of any character</li>
<li><em>+</em> - will match 1 or more of any character</li>
<li><em>!</em> - will match exactly 1 of any character</li>
</ul>
</div></blockquote>
<p>As an example, imagine that you have enabled the required prefix
matching on your <code class="docutils literal notranslate"><span class="pre">User.email</span></code> column. And lets say that you want to
find everyone with an email address that contains the name ‘frank’
before the <code class="docutils literal notranslate"><span class="pre">&#64;</span></code> sign. You can use either of the following patterns
to discover those users.</p>
<blockquote>
<div><ul class="simple">
<li><em>*frank*&#64;</em></li>
<li><em>*frank*&#64;</em></li>
</ul>
</div></blockquote>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Like queries implicitly start at the beginning of strings
checked, so if you want to match a pattern that doesn’t start at
the beginning of a string, you should prefix it with one of the
wildcard characters (like <code class="docutils literal notranslate"><span class="pre">*</span></code> as we did with the ‘frank’ pattern).</p>
</div>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">limit</code><span class="sig-paren">(</span><em>offset</em>, <em>count</em><span class="sig-paren">)</span></dt>
<dd><p>Will limit the number of results returned from a query:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># returns the most recent 25 users</span>
<span class="n">User</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;-created_at&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">limit</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">25</span><span class="p">)</span><span class="o">.</span><span class="n">execute</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">order_by</code><span class="sig-paren">(</span><em>column</em><span class="sig-paren">)</span></dt>
<dd><p>When provided with a column name, will sort the results of your query:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># returns all users, ordered by the created_at column in</span>
<span class="c1"># descending order</span>
<span class="n">User</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;-created_at&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">execute</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">replace</code><span class="sig-paren">(</span><em>**kwargs</em><span class="sig-paren">)</span></dt>
<dd><p>Copy the Query object, optionally replacing the filters, order_by, or
limit information on the copy. This is mostly an internal detail that
you can ignore.</p>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">select</code><span class="sig-paren">(</span><em>*column_names</em>, <em>**kwargs</em><span class="sig-paren">)</span></dt>
<dd><p>Select the provided column names from the model, do not return an entity,
do not involve the rom session, just get the raw and/or processed column
data from Redis.</p>
<p>Keyword-only arguments:</p>
<blockquote>
<div><ul class="simple">
<li><dl class="first docutils">
<dt><em>include_pk=False</em> - whether to include the primary key in the</dt>
<dd>returned data (we need to get this in some cases, so we fetch
it anyway; if you want it, we can return it to you - just be
careful with the namedtuple option - see the warning below)</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt><em>decode=True</em> - whether to take a pass through normal data</dt>
<dd>decoding in the model (will not return an entity/model)</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt><em>ff=_dict_data_factory</em> - the type of data to return from the</dt>
<dd>select after all filters/limits/order_by are applied</dd>
</dl>
</li>
</ul>
</div></blockquote>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">If <code class="docutils literal notranslate"><span class="pre">include_pk</span> <span class="pre">=</span> <span class="pre">True</span></code> and if you don’t provide
the primary key column, it will be appended to your list of columns.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">if you want to provide a new factory function for the returned
data, it must be of the form (below is the actual dict factory
function)</p>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">_dict_data_factory</span><span class="p">(</span><span class="n">columns</span><span class="p">):</span>
    <span class="n">_dict</span> <span class="o">=</span> <span class="nb">dict</span>
    <span class="n">_zip</span> <span class="o">=</span> <span class="nb">zip</span>
    <span class="k">def</span> <span class="nf">make</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
        <span class="c1"># do whatever you need to turn your tuple of columns plus</span>
        <span class="c1"># your list of data into whatever you want:</span>
        <span class="k">return</span> <span class="n">_dict</span><span class="p">(</span><span class="n">_zip</span><span class="p">(</span><span class="n">columns</span><span class="p">,</span> <span class="n">data</span><span class="p">))</span>
    <span class="k">return</span> <span class="n">make</span>
</pre></div>
</div>
<p>Available factory functions:</p>
<blockquote>
<div><ul class="simple">
<li><em>``rom.query._dict_data_factory``</em> - default</li>
<li><em>``rom.query._list_data_factory``</em> - lowest overhead, as the
<code class="docutils literal notranslate"><span class="pre">data</span></code> passed in above is a list that you can do anything to</li>
<li><em>``rom.query._tuple_data_factory``</em> - when you want tuples instead</li>
<li><em>``rom.query._namedtuple_data_factory``</em> - get namedtuples, see
see warning below</li>
</ul>
</div></blockquote>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">If you use the <code class="docutils literal notranslate"><span class="pre">_namedtuple_data_factory</span></code>, and your
columns include underscore prefixes, they will be stripped. If this
results in a name collision, you <em>will</em> get an exception. If you want
differerent behavior, write your own 20 line factory function that
does exactly what you want, and pass it; they are really easy!</p>
</div>
</dd></dl>

<dl class="method">
<dt>
<code class="descname">startswith</code><span class="sig-paren">(</span><em>**kwargs</em><span class="sig-paren">)</span></dt>
<dd><p>When provided with keyword arguments of the form <code class="docutils literal notranslate"><span class="pre">col=prefix</span></code>, this
will limit the entities returned to those that have a word with the
provided prefix in the specified column(s). This requires that the
<code class="docutils literal notranslate"><span class="pre">prefix=True</span></code> option was provided during column definition.</p>
<p>Usage:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">User</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s1">&#39;user@&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">execute</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

</dd></dl>

<dl class="exception">
<dt>
<em class="property">exception </em><code class="descclassname">rom.</code><code class="descname">QueryError</code></dt>
<dd><p>Bases: <a class="reference internal" href="exceptions.html#rom.exceptions.InvalidOperation" title="rom.exceptions.InvalidOperation"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.exceptions.InvalidOperation</span></code></a></p>
<p>Raised when arguments to <code class="docutils literal notranslate"><span class="pre">Model.get_by()</span></code> or <code class="docutils literal notranslate"><span class="pre">Query.filter</span></code> are not valid</p>
</dd></dl>

<dl class="exception">
<dt>
<em class="property">exception </em><code class="descclassname">rom.</code><code class="descname">RestrictError</code></dt>
<dd><p>Bases: <a class="reference internal" href="exceptions.html#rom.exceptions.InvalidOperation" title="rom.exceptions.InvalidOperation"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.exceptions.InvalidOperation</span></code></a></p>
<p>Raised when deleting an object referenced by other objects</p>
</dd></dl>

<dl class="function">
<dt>
<code class="descclassname">rom.</code><code class="descname">SIMPLE</code><span class="sig-paren">(</span><em>val</em><span class="sig-paren">)</span></dt>
<dd><p>This is a basic case-sensitive “sorted order” index keygen function for
strings. This will return a value that is suitable to be used for ordering
by a 7-byte prefix of a string (that is 7 characters from a byte-string, and
1.75-7 characters from a unicode string, depending on character -&gt; encoding
length).</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">Case sensitivity is based on the (encoded) byte prefixes of the
strings/text being indexed, so ordering <em>may be different</em> than a native
comparison ordering (especially if an order is different based on
characters past the 7th encoded byte).</p>
</div>
</dd></dl>

<dl class="function">
<dt>
<code class="descclassname">rom.</code><code class="descname">SIMPLE_CI</code><span class="sig-paren">(</span><em>val</em><span class="sig-paren">)</span></dt>
<dd><p>The same as SIMPLE, only case-insensitive.</p>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">SaferDateTime</code><span class="sig-paren">(</span><em>required=False</em>, <em>default=&lt;object object&gt;</em>, <em>unique=False</em>, <em>index=False</em>, <em>keygen=None</em>, <em>prefix=False</em>, <em>suffix=False</em>, <em>keygen2=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.DateTime" title="rom.columns.DateTime"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.DateTime</span></code></a></p>
<p>A (safer) datetime column (see Issue #109 or the below note for more
information)</p>
<p>All standard arguments supported. See <code class="docutils literal notranslate"><span class="pre">Column</span></code> for details on supported
arguments.</p>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">SaferDateTime</span><span class="p">()</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">tzinfo objects are not stored</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">what makes this “safer” than other datetime objects is that there
are exactly two types of values that can be set here: a <code class="docutils literal notranslate"><span class="pre">datetime</span></code>
object, or a <code class="docutils literal notranslate"><span class="pre">str</span></code> that can represent a float, which is the number of
seconds since the unix epoch.</p>
</div>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">String</code><span class="sig-paren">(</span><em>required=False</em>, <em>default=&lt;object object&gt;</em>, <em>unique=False</em>, <em>index=False</em>, <em>keygen=None</em>, <em>prefix=False</em>, <em>suffix=False</em>, <em>keygen2=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>A plain string column (str in 2.x, bytes in 3.x). Trying to save unicode
strings will probably result in an error, if not corrupted data.</p>
<p>All standard arguments and String/Text arguments supported. See <code class="docutils literal notranslate"><span class="pre">Column</span></code>
for details on supported arguments.</p>
<p>This column can be indexed in one of five ways - a sorted index on a 7
byte prefix of the value (<code class="docutils literal notranslate"><span class="pre">keygen=rom.SIMPLE</span></code>), a sorted index on a
lowercased 7 byte prefix of the value (<code class="docutils literal notranslate"><span class="pre">keygen=rom.SIMPLE_CI</span></code>),
a case-insensitive full-text index (<code class="docutils literal notranslate"><span class="pre">keygen=rom.FULL_TEXT</span></code>),
a case-sensitive identity index (<code class="docutils literal notranslate"><span class="pre">keygen=rom.IDENTITY</span></code>), and a
case-insensitive identity index (<code class="docutils literal notranslate"><span class="pre">keygen=rom.IDENTITY_CI</span></code>).</p>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">String</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Suffix</code><span class="sig-paren">(</span><em>attr</em>, <em>suffix</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">tuple</span></code></p>
<dl class="attribute">
<dt>
<code class="descname">attr</code></dt>
<dd><p>Alias for field number 0</p>
</dd></dl>

<dl class="attribute">
<dt>
<code class="descname">suffix</code></dt>
<dd><p>Alias for field number 1</p>
</dd></dl>

</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Text</code><span class="sig-paren">(</span><em>required=False</em>, <em>default=&lt;object object&gt;</em>, <em>unique=False</em>, <em>index=False</em>, <em>keygen=None</em>, <em>prefix=False</em>, <em>suffix=False</em>, <em>keygen2=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>A unicode string column. Behavior is more or less identical to the String
column type, except that unicode is supported (unicode in 2.x, str in 3.x).
UTF-8 is used by default as the encoding to bytes on the wire, which <em>will</em>
affect <code class="docutils literal notranslate"><span class="pre">rom.SIMPLE</span></code> and <code class="docutils literal notranslate"><span class="pre">rom.SIMPLE_CI</span></code> indexes.</p>
<p>All standard arguments supported. See <code class="docutils literal notranslate"><span class="pre">Column</span></code> for details on supported
arguments.</p>
<p>This column can be indexed in one of five ways - a sorted index on a 7
byte prefix of the value (<code class="docutils literal notranslate"><span class="pre">keygen=rom.SIMPLE</span></code>), a sorted index on a
lowercased 7 byte prefix of the value (<code class="docutils literal notranslate"><span class="pre">keygen=rom.SIMPLE_CI</span></code>),
a case-insensitive full-text index (<code class="docutils literal notranslate"><span class="pre">keygen=rom.FULL_TEXT</span></code>),
a case-sensitive identity index (<code class="docutils literal notranslate"><span class="pre">keygen=rom.IDENTITY</span></code>), and a
case-insensitive identity index (<code class="docutils literal notranslate"><span class="pre">keygen=rom.IDENTITY_CI</span></code>).</p>
<p>For the 7 byte prefix/suffixes on indexes using the <code class="docutils literal notranslate"><span class="pre">rom.SIMPLE</span></code> and
<code class="docutils literal notranslate"><span class="pre">rom.SIMPLE_CI</span></code> keygen, because we use UTF-8 to encode text, a single
character can turn into 1-3 bytes, so may not be useful in practice.</p>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
</pre></div>
</div>
</dd></dl>

<dl class="class">
<dt>
<em class="property">class </em><code class="descclassname">rom.</code><code class="descname">Time</code><span class="sig-paren">(</span><em>required=False</em>, <em>default=&lt;object object&gt;</em>, <em>unique=False</em>, <em>index=False</em>, <em>keygen=None</em>, <em>prefix=False</em>, <em>suffix=False</em>, <em>keygen2=None</em><span class="sig-paren">)</span></dt>
<dd><p>Bases: <a class="reference internal" href="columns.html#rom.columns.Column" title="rom.columns.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.columns.Column</span></code></a></p>
<p>A time column. Timezones are ignored.</p>
<p>All standard arguments supported. See <code class="docutils literal notranslate"><span class="pre">Column</span></code> for details on supported
arguments.</p>
<p>Used via:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">col</span> <span class="o">=</span> <span class="n">Time</span><span class="p">()</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">tzinfo objects are not stored</p>
</div>
</dd></dl>

<dl class="exception">
<dt>
<em class="property">exception </em><code class="descclassname">rom.</code><code class="descname">UniqueKeyViolation</code></dt>
<dd><p>Bases: <a class="reference internal" href="exceptions.html#rom.exceptions.ORMError" title="rom.exceptions.ORMError"><code class="xref py py-class docutils literal notranslate"><span class="pre">rom.exceptions.ORMError</span></code></a></p>
<p>Raised when trying to save an entity without a distinct column value</p>
</dd></dl>

</div>
<p><a class="reference internal" href="columns.html#module-rom.columns" title="rom.columns"><code class="xref py py-mod docutils literal notranslate"><span class="pre">rom.columns</span></code></a>
<a class="reference internal" href="exceptions.html#module-rom.exceptions" title="rom.exceptions"><code class="xref py py-mod docutils literal notranslate"><span class="pre">rom.exceptions</span></code></a>
<a class="reference internal" href="indexm.html#module-rom.index" title="rom.index"><code class="xref py py-mod docutils literal notranslate"><span class="pre">rom.index</span></code></a>
<a class="reference internal" href="model.html#module-rom.model" title="rom.model"><code class="xref py py-mod docutils literal notranslate"><span class="pre">rom.model</span></code></a>
<a class="reference internal" href="query.html#module-rom.query" title="rom.query"><code class="xref py py-mod docutils literal notranslate"><span class="pre">rom.query</span></code></a>
<a class="reference internal" href="util.html#module-rom.util" title="rom.util"><code class="xref py py-mod docutils literal notranslate"><span class="pre">rom.util</span></code></a></p>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="index.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">rom Package</a><ul>
<li><a class="reference internal" href="#sponsorships-available">Sponsorships Available</a></li>
<li><a class="reference internal" href="#documentation">Documentation</a></li>
<li><a class="reference internal" href="#what">What</a></li>
<li><a class="reference internal" href="#why">Why</a></li>
<li><a class="reference internal" href="#what-is-available">What is available</a></li>
<li><a class="reference internal" href="#getting-started">Getting started</a></li>
<li><a class="reference internal" href="#lua-support">Lua support</a></li>
<li><a class="reference internal" href="#expiring-models-ttls">Expiring models/TTLs</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="index.html"
                        title="previous chapter">Welcome to the documentation for the Redis object Mapper</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="columns.html"
                        title="next chapter"><code class="docutils literal notranslate"><span class="pre">columns</span></code> Module</a></p>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="_sources/rom.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3>Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="columns.html" title="columns Module"
             >next</a> |</li>
        <li class="right" >
          <a href="index.html" title="Welcome to the documentation for the Redis object Mapper"
             >previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">rom 1.0.4 documentation</a> &#187;</li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
        &#169; Copyright 2013-2015, Josiah Carlson.
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.2.
    </div>
  </body>
</html>